package gptma.bo.dao.querier;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * This class represents a set of criteria used for a search. A criteria is
 * composed of a property (matches given entity property), a mode (=, <=, in,
 * etc.) and a value. For string values, user can also specify case-sensitivity
 * 
 * Right now, criteria are ANDED
 * 
 * @author xcl
 * 
 */
public class CriterionSet extends CriteriaListHolder {

	private List<CollectionElementCriterion> collectionCriteria;

	/**
	 * additional relationships that will be fetched with the base entity. For
	 * each relationship, the Boolean enables to precise if the fetch is
	 * mandatory (inner join), or not (left join) WARNING: only 1
	 * List-relationship can be eagerly fetched this way (SQL limitation) TODO:
	 * use Set to implement relationships instead of List
	 * 
	 * @see http 
	 *      ://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&
	 *      f=78&t=003855
	 * @see http://opensource.atlassian.com/projects/hibernate/browse/EJB-304
	 */
	private Map<String, Boolean> fetchedRelationships;

	/**
	 * Constructor
	 */
	public CriterionSet() {
		super();
		this.collectionCriteria = new ArrayList<CollectionElementCriterion>();
		this.fetchedRelationships = new HashMap<String, Boolean>();
	}

	/**
	 * Constructor, searchMode: equals
	 * 
	 * @param property
	 *            property
	 * @param value
	 *            value
	 */
	public CriterionSet(String property, Object value) {
		this();
		addCriterion(property, value);
	}

	/**
	 * Constructor
	 * 
	 * @param property
	 *            property
	 * @param searchMode
	 *            searchMode
	 * @param value
	 *            value
	 */
	public CriterionSet(String property, SearchMode searchMode, Object value) {
		this();
		addCriterion(property, searchMode, value);
	}

	public CriterionSet addCollectionCriterion(
			CollectionElementCriterion collectionElementCriterion) {
		collectionCriteria.add(collectionElementCriterion);
		return this;
	}

	/**
	 * Set the query to fetch the given relationship
	 * 
	 * @param relationship
	 *            fetched relationship
	 * @param mandatory
	 *            is the fetch mandatory (inner join) or not (left join)
	 * @return criterionSet instance
	 */
	public CriterionSet addFetchedRelationship(String relationship,
			boolean mandatory) {
		fetchedRelationships.put(relationship, mandatory);
		return this;
	}

	/**
	 * @return the fetchedRelationships
	 */
	public Map<String, Boolean> getFetchedRelationships() {
		return fetchedRelationships;
	}

	/**
	 * @return the collectionCriteria
	 */
	public List<CollectionElementCriterion> getCollectionCriteria() {
		return collectionCriteria;
	}

}
